package cn.wolfcode.crm.shiro;

import cn.wolfcode.crm.domain.Employee;
import cn.wolfcode.crm.mapper.EmployeeMapper;
import cn.wolfcode.crm.mapper.PermissionMapper;
import cn.wolfcode.crm.mapper.RoleMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component("crmRealm")
public class CRMRealm extends AuthorizingRealm { //获取认证信息

    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    //从spring中找到CredentialsMatcher 注入进去
    //将容器中的配置的凭证匹配器注入给当前的 Realm 对象
    //在该 Realm 中使用指定的凭证匹配器来完成密码匹配的操作
    @Autowired
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        super.setCredentialsMatcher(credentialsMatcher);
    }

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String principal = (String) token.getPrincipal();
        //暂且使用假数据来模拟真实的账号和密码
       /* String username = "zhangsan";
        String password = "666";*/
        Employee employee = employeeMapper.selectByName(principal);
        //如果账号正确，返回一个 AuthenticationInfo 对象
        if (employee != null) {
            // 第一个参数是subject里面的身份信息  希望以后获得员工身份信息
            return new SimpleAuthenticationInfo(employee,//员工信息
                    //登录的时候对输入的密码解密  输入加入的盐即可
                    employee.getPassword(),//密码
                    //登录的时候告诉他用的盐是啥
                    ByteSource.Util.bytes(employee.getName()),
                    "crmRealm"//当前 Realm 的名称
            );
        }
        return null;
    }

    //获取授权信息
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //授权信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //获取当前登录用户
        Subject subject = SecurityUtils.getSubject();
        Employee employee = (Employee) subject.getPrincipal();
        if (employee.isAdmin()) {
            info.addStringPermission("*:*");
            //加上角色
            info.addRole("admin");
        } else {
            //当前登录用户有哪些角色编码,有哪些权限表达式,全部查出来之后添加到info中
            List<String> roles = roleMapper.selectSnByEmpId(employee.getId());
            info.addRoles(roles);
            List<String> permissions = permissionMapper.getPermissionsByEmpId(employee.getId());
            info.addStringPermissions(permissions);
        }
        return info;
    }
}
